package thread;

// 标准库提供了Thread类，使用的时候就继承该类
// Thread类 相当于是对操作系统中的线程进行的封装
class MyThread extends Thread {
    // 重写的run里的逻辑就是该线程要执行的工作！！
    // 所以：此处创建子类并且重写run方法其实就相当于“安排任务”
    @Override
    public void run() {
        while (true) {
            System.out.println("hello thread!");
            try {
                Thread.sleep(1000); // 休眠1000ms，也就是让线程阻塞一段时间（参数时间长度）
                // 受查异常：一定要 抛异常！！
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 进行 多线程创建 演示
public class Demo1 {
    public static void main(String[] args) {
        // 创建MyThread实例：创建实例并不会在系统中真的创建一个线程！！
        MyThread myThread = new MyThread();
        // 调用 start方法的时候才是真正创建出一个新的线程！！！
        // 而此时新的线程就会执行run里面的逻辑，一直到run里的代码执行完新的线程才是运行结束。
        myThread.start();
        // 调用 start方法 其实是另外启动了一个线程来执行Thread中的run方法！
        // 新的线程是一个单独的执行流，和现有线程的执行流不相关。 并发（并发+并行）执行

        // 如果main方法里面没有Thread子类创建的实例对象调用start方法，则调用的其实是main里面自带的默认线程（也叫 主线程）
        // main主线程（JVM创建）和MyThread创建出来的新线程是一个“并发执行”的关系。（但是此处的并发其实是指：并发+并行）
        // 并发执行：两边同时执行，各自安好、互不干扰！
        // MyThread的线程中run是该线程的入口方法

        while (true) {
            System.out.println("hello main"); // 主线程中的
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 不完全的交替打印：
        // 操作系统进行调度线程的时候是一个“随机”的过程；（其实也不是一个严格的随机，但是是不确定的）
        // 执行sleep的时候线程进入阻塞，当sleep时间到则线程恢复就绪状态参与线程调度；
        // 当两个线程都参与调度的时候谁先谁后是不确定的！
        // 这种不确定行为： “抢占式执行”！！！
    }
}
